package com.klun.concDesign.chapterFive.NIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;

public class MultiThreadClient {
    private Selector selector;

    /**
     * 初始化
     * @param ip
     * @param port
     * @throws IOException
     */
    public void init (String ip, int port) throws IOException {
        SocketChannel channel = SocketChannel.open();
        channel.configureBlocking(false);
        // 创建一个 selector
        this.selector = SelectorProvider.provider().openSelector();

        channel.connect(new InetSocketAddress(ip,port));
        // 绑定 selector 和 channel 并注册事件 连接
        channel.register(selector, SelectionKey.OP_CONNECT);
    }

    public void working() throws IOException {
        System.out.println("client 开始 工作");
        while (true){
            if(!selector.isOpen()){
                System.out.println(" selector 为关闭状态");
                break;
            }
            selector.select();
            Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                // 连接事件发生
                if(key.isConnectable()){
                    connect(key);
                }else if(key.isReadable()){
                    read(key);
                }
            }
        }
    }

    public void connect(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel)key.channel();
        // 如果正在连接 则完成连接 ??? 这一步无法执行
        if(channel.isConnectionPending()){
            channel.finishConnect();
        }
        channel.configureBlocking(false);
        channel.write(ByteBuffer.wrap(new String("hello server!\r\n").getBytes()));
        channel.register(this.selector,SelectionKey.OP_READ);
    }

    public void read(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel)key.channel();
        // 创建读取的缓存区
        ByteBuffer allocate = ByteBuffer.allocate(100);
        channel.read(allocate);
        byte[] array = allocate.array();
        String msg = new String(array).trim();
        System.out.println("客户端收到的回复"+msg);
        // 关闭channel 和 selector
        channel.close();
        key.selector().close();
    }

}
